#define DEBUG
#include <cstdio>
#include <cmath>

using namespace std;

const int maxn=50010, maxm=100010, maxlogn=16;

void swap(int &a, int &b) {
  int temp;
  temp=a, a=b, b=temp;
}

class Graph {
public:
  int n, m, ind[maxn+1], to[2*maxn-1], link[2*maxn-1], st[maxn+1], en[maxn+1], seq[2*maxn+1], f[maxn+1][maxlogn+1], dep[maxn+1];

  void addSide(int x, int y) {
    m++;
    to[m] = y;
    link[m] = ind[x];
    ind[x] = m;
  }

  void build(int o, int fa) {
    f[o][0] = fa;
    dep[o] = dep[fa]+1;
    st[o] = ++seq[0];
    seq[st[o]] = o;

    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	build(to[i], o);
      }
    }

    en[o] = ++seq[0];
    seq[en[o]] = o;
  }
  
  void initF() {
    build(0, 0);

    for (int i=1; i<=maxlogn; i++) {
      for (int j=0; j<=n; j++) {
	f[j][i] = f[f[j][i-1]][i-1];
      }
    }
  }

  int lca(int u, int v) {
    if (dep[u]<dep[v]) {
      swap(u, v);
    }
    for (int i=maxlogn; i>=0; i--) {
      if (dep[f[u][i]]>=dep[v]) {
	u = f[u][i];
      }
    }
    if (u==v) {
      return u;
    }
    for (int i=maxlogn; i>=0; i--) {
      if (f[u][i]!=f[v][i]) {
	u = f[u][i], v = f[v][i];
      }
    }
    return f[u][0];
  }
};

class Ques {
public:
  int u, v, a, b, t, id, lca;
};

void sort(Ques *a, int l, int r) {
  int i=l, j=r, mid[2]={a[(l+r)/2].t, a[(l+r)/2].v};
  Ques temp;
  for (; i<=j; ) {
    for (; a[j].t>mid[0] || (a[j].t==mid[0] && a[j].v>mid[1]); j--);
    for (; a[i].t<mid[0] || (a[i].t==mid[0] && a[i].v<mid[1]); i++);
    if (i<=j) {
      temp=a[i], a[i]=a[j], a[j]=temp;
      i++, j--;
    }
  }
  if (i<r) {
    sort(a, i, r);
  }
  if (j>l) {
    sort(a, l, j);
  }
}

void move_step(int node, int &now, int *col, int *apple, int *flag) {
  if (node!=0) {
    int x=apple[col[node]], y;
    apple[col[node]] += flag[node];
    y=apple[col[node]];
    if (x && !y) {
      now--;
    } else if (!x && y) {
      now++;
    }
    flag[node] = -flag[node];
  }
}

int main() {
#ifdef DEBUG
  freopen("3360.in", "r", stdin);
  freopen("3360.out", "w", stdout);
#endif

  static int col[maxn+1], block[2*maxn+1];
  static Graph g;
  int n, m;
  scanf("%d %d", &n, &m);
  g.n = n;
  for (int i=1; i<=n; i++) {
    scanf("%d", col+i);
  }
  for (int i=1; i<=n; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    g.addSide(u, v);
    g.addSide(v, u);
  }

  g.initF();
  int block_size=ceil(sqrt(2*n+2));
  for (int i=1; i<=2*n+2; i++) {
    block[i] = i/block_size+1;
  }
  block[0] = (2*n+2)/block_size+1;

  static Ques ques[maxm+1];
  for (int i=1; i<=m; i++) {
    int u, v;
    scanf("%d %d %d %d", &u, &v, &ques[i].a, &ques[i].b);
    if (g.st[u]>g.st[v]) {
      swap(u, v);
    }
    ques[i].lca = g.lca(u, v);
    if (ques[i].lca==u) {
      ques[i].u = g.st[u];
      ques[i].lca = 0;
    } else {
      ques[i].u = g.en[u];
    }
    ques[i].v = g.st[v];
    ques[i].t = block[ques[i].u];
    ques[i].id = i;
  }
  sort(ques, 1, m);

  static int ans[maxm+1], apple[maxn+1], flag[maxn+1];
  for (int i=1; i<=n; i++) {
    flag[i] = 1;
  }
  for (int i=1, l=1, r=0, now=0; i<=m; i++) {
    int u=ques[i].u, v=ques[i].v, a=ques[i].a, b=ques[i].b, id=ques[i].id, lca=ques[i].lca;
    if (l<u) {
      for (; l<u; ) {
	move_step(g.seq[l++], now, col, apple, flag);
      }
    } else if (u<l) {
      for (; l>u;) {
	move_step(g.seq[--l], now, col, apple, flag);
      }
    }
    if (r<v) {
      for (; r<v; ) {
	move_step(g.seq[++r], now, col, apple, flag);
      }
    } else if (v<r) {
      for (; r>v; ) {
	move_step(g.seq[r--], now, col, apple, flag);
      }
    }

    ans[id] = now;
    if (lca!=0 && !apple[col[lca]]) {
      ans[id]++;
    }
    if (a!=b && apple[a] && apple[b]) {
      ans[id]--;
    }
  }

  for (int i=1; i<=m; i++) {
    printf("%d\n", ans[i]);
  }

  fclose(stdin);
  fclose(stdout);
  return 0;
}
